<?php
/**
 * 画像表示用コントローラ
 * 
 * @package Common
 * @author hiasa-ryousuke@systemsoft.co.jp
 * @since 2010/11/9
 */
class Common_ImgController extends Zend_Controller_Action
{
    
    /**
     * レジストリのconfigを格納
     * 
     * @var object
    */
    private $_config = null;
        
    
    /**
     * サムネイル表示のメインアクション
     *
     * @access public
     * @return void
     */
    public function thumbnailAction()
    {
        $configObject = Zend_Registry::get('config');
        $this->_config = $configObject->toArray();
        $image_file_path = '';
        $width  = '';
        $height = '';
        $this->checkRequest($image_file_path, $width, $height);
        $this->makeThumnailDir();
        $size = 'w'.$width.'-'.'h'.$height;
        $thumnail_file_path = $this->getThumbnailFilePath($size);
        if (file_exists($thumnail_file_path)){
            if (filemtime($thumnail_file_path) < filemtime($image_file_path)){
                unlink($thumnail_file_path);
            }
        }
        if (!file_exists($thumnail_file_path)){
            $this->generateThumbnailImage($image_file_path, $thumnail_file_path, $width, $height);
        }
        Apm_Util::outputXPassThroutgh();
        $extension = pathinfo($image_file_path, PATHINFO_EXTENSION);
        Apm_Util::outputImage($thumnail_file_path, $extension);
        exit;
    }
    
    /**
     * リクエストの妥当性をチェックし、画像パスとサイズをセットするメソッド
     * 
     * @param string &$width  リクエストパラメータで指定された画像の幅
     * @param string &$height リクエストパラメータで指定された画像の高さ
     * @access private
     * @return void
     */
    private function checkRequest(&$image_file_path, &$width, &$height)
    {
        $nosize_flg = FALSE;
        if($this->getRequest()->width == FALSE || $this->getRequest()->height == FALSE){
            $nosize_flg = TRUE;
        }
        else{
            $width  = $this->getRequest()->width;
            $height = $this->getRequest()->height;
        }
        
        if($this->getRequest()->file == FALSE){
            if($nosize_flg == TRUE){
                $this->raiseErrorNoFile();
            }
            $this->raiseErrorNoFile($width, $height);
        }
        $image_file_path = $this->getImageFilePath();
        if(!file_exists($image_file_path)){
            if($nosize_flg == TRUE){
                $this->raiseErrorNoFile();
            }
            $this->raiseErrorNoFile($width, $height);
        }
        if($nosize_flg == TRUE){
            $this->raiseErrorNoSize($image_file_path);
        }
    }
        
    /**
     * サムネイルを生成するメソッド
     *
     * @param string $org_file_path 元画像のパス
     * @param string $new_file_path 生成するサムネイルのパス
     * @param int $width  生成するサムネイルの高さ
     * @param int $height 生成するサムネイルの幅
     * @access private
     * @return void
     */
    private function generateThumbnailImage($org_file_path, $new_file_path, $width, $height)
    {
        $image = new Imagick($org_file_path);
        $image->thumbnailImage($width, $height, true);
        $fp = fopen($new_file_path, 'wb');
        fwrite($fp, $image);
        fclose($fp);
    }
    
    /**
     * サムネイルファイルのパスを返すメソッド
     *
     * @param string $size サムネイルのサイズ　(例)w75-h75
     * @access private
     * @return string サムネイルファイルのパス
     */
    private function getThumbnailFilePath($size)
    {
        return $this->getThumnailDir() . DIRECTORY_SEPARATOR . $this->getThumnailFileName($size);
    }
    
    /**
     * サムネイルのファイル名を返すメソッド
     *
     * @param string $size サムネイルのサイズ　(例)w75-h75
     * @access private
     * @return string サムネイルのファイル名
     */
    private function getThumnailFileName($size)
    {
        $tmp = array();
        $tmp = explode('/',$this->getRequestFilePath());
        $file = array_pop($tmp);
        return sprintf('%s.%s', $file, $size);
    }
    
    /**
     * 元画像のパスを返すメソッド
     *
     * @access private
     * @return string 元画像のパス
     */
    private function getImageFilePath()
    {
        $basepath = $this->_config['apm']['apl']['image']['basepath'];
        $image_file_path  = '';
        $image_file_path .= $basepath;
        $image_file_path .= DIRECTORY_SEPARATOR;
        $image_file_path .= $this->getRequestFilePath();
        if ($this->isImageCommonFile($basepath, $image_file_path) && !file_exists($image_file_path))
        {
            return $this->getOldFilePath($image_file_path);
        }    
        return $image_file_path;
    }
    
    /**
     * imgCommonディレクトリ内の特定のディレクリかを判定するメソッド
     * @param string $basepath  ファイルサーバーの絶対パス
     * @param string $image_file_path  ファイルサーバー以下の画像ファイルのパス
     * 
     * @access private
     * @return bool
     */
    private function isImageCommonFile($basepath, $image_file_path){
        $pattern_array = array(
        	DIRECTORY_SEPARATOR . Apm_Config_Rstdtl::IMG_COMMON_PATH,
        	DIRECTORY_SEPARATOR . Apm_Config_Rstdtl::IMG_COMMON_PANORAMAPATH,
        	DIRECTORY_SEPARATOR . Apm_Config_Rstdtl::IMG_COMMON_MADORI3DPATH
        );
        foreach($pattern_array as $chk_dir){
            if(ereg($basepath.$chk_dir, $image_file_path)){
                return TRUE;
            }
            else{
                continue;
            }
        }
        return FALSE;
    }
    
    
    /**
     * 旧apaman.com仕様の画像ファイルのパスを返すメソッド
     * @param string $image_file_path  画像の絶対パス
     *  
     * @access private
     * @return string 画像ファイルのパス
     */
    private function getOldFilePath($image_file_path){
        $path_array = explode('/', $image_file_path);
        unset($path_array[8]);
        unset($path_array[9]);
        unset($path_array[10]);
        return implode('/',$path_array);
    }
    
    /**
     * リクエストされたファイルのパスを正規化して返すメソッド
     * 
     * 先頭にスラッシュが付加されていたら取り除く
     *
     * @access private
     * @return string リクエストされたファイルのパス
     */
    private function getRequestFilePath()
    {
        $request_file_path = $this->getRequest()->file;
        while(preg_match('/^\//',$request_file_path)){
            $request_file_path = ltrim($request_file_path,'/');
        }
        return $request_file_path;
    }
    
    /**
     * キャッシュのパスを返すメソッド
     *
     * @access private
     * @return string キャッシュのパス
     */
    private function getThumnailDir()
    {
        $thumnail_dir_array = array();
        $thumnail_dir_array = explode('/', $this->getRequestFilePath());
        array_pop($thumnail_dir_array);
        $directory = '';
        $directory .= dirname(APPLICATION_PATH);
        $directory .= DIRECTORY_SEPARATOR;
        $directory .= 'temp';
        $directory .= DIRECTORY_SEPARATOR;
        $directory .= 'thumbnail';
        foreach($thumnail_dir_array as $buf){
            $directory .= DIRECTORY_SEPARATOR;
            $directory .= $buf;
        }
        return $directory;
    }
    
    /**
     * キャッシュのディレクトリを生成するメソッド
     *
     * @access private
     * @return void
     */
    private function makeThumnailDir()
    {
        $thumnail_dir = $this->getThumnailDir();
        @mkdir($thumnail_dir, 0755 , TRUE);
    }
    
    /**
     * リクエストパラメータにサイズ指定がなかった場合のエラー処理として、元画像を出力する
     *
     * @access private
     * @return void
     */
    private function raiseErrorNoSize($image_file_path)
    {
        __log_debug(__FILE__, __LINE__, __METHOD__, '---------->>>');
        $extension = pathinfo($image_file_path, PATHINFO_EXTENSION);
        Apm_Util::outputImage($image_file_path, $extension);
        __log_debug(__FILE__, __LINE__, __METHOD__, 'サムネイルに対する縦・横のサイズ指定がされていないため、元画像を出力しました');
        __log_debug(__FILE__, __LINE__, __METHOD__, '----------<<<');
        exit;
    }
    
    /**
     * 指定された画像がなかった場合のエラー処理として、No Image画像を出力する
     *
     * @param string &$width  リクエストパラメータで指定された画像の幅
     * @param string &$height リクエストパラメータで指定された画像の高さ
     * @access private
     * @return void
     */
    private function raiseErrorNoFile($width = '75', $height = '75')
    {
        __log_debug(__FILE__, __LINE__, __METHOD__, '---------->>>');
        if($width == '480' && $height == '480'){
            $no_image_file_path = $this->_config['apm']['apl']['image']['cmsurl'].'images/common/nophoto_480_480.gif';
        }
        elseif($width == '75' && $height == '75'){
            $no_image_file_path = $this->_config['apm']['apl']['image']['cmsurl'].'images/common/nophoto_75_75.gif';
        }
        else{
            $no_image_file_path = $this->_config['apm']['apl']['image']['cmsurl'].'images/common/nophoto_75_75.gif';
        }
        Apm_Util::outputImage($no_image_file_path , 'gif');
        __log_debug(__FILE__, __LINE__, __METHOD__, '指定された画像が見つかりません');
        __log_debug(__FILE__, __LINE__, __METHOD__, '----------<<<');
        exit;
    }
    
}

